#include "stdafx.h"
//
//#include <stdio.h>
//#include <string.h>
#include <math.h>
#include "str_unit.h"
#include "internal.h"
#include "actual_testing.h"
#define _CRT_SECURE_NO_WARNINGS

//Messages
#define _ERROR_CANT_OPEN_INPUT_FILE "ERROR: can't open input file %s\n"
#define _ERROR_CANT_OPEN_OUTPUT_FILE "ERROR: can't open output file %s\n"
#define _ERROR_NO_INPUT_DATA "ERROR: file %s with input data missing\n"
#define _ERROR_TEST_TIMEOUT "ERROR: test execution exceeds maximum time of %f seconds\n"
#define _FATAL_ERROR_DURING_TEST_EXECUTION "ERROR: fatal error executing tested function\n"
#define _ERROR_BAD_POINTER_RETURNED "ERROR: bad pointer returned from tested function\n"
#define _ERROR_STUB_CALLED "ERROR: linker coudn't find student version of tested function\n"
#define _ERROR_BAD_STRCAT_CALL "ERROR: Wrong strcat use coping from \"%s\" to \"%s\"\n"
#define _ERROR_BAD_STRCPY_CALL "ERROR: Wrong strcpy use coping from \"%s\"\n"

///////////////////////////////////////Global variables for testing routines
//Function input data stream
static FILE *funcstream;
//output data stream
static FILE *ostream;
//Max time in seconds for 1 test
static float testingtime=1;
//Array of testing routines
//Indexes are: variant, report and funcnumber
//Filled in FillTestRoutines
static __testroutine tstroutines[31][10][10]={};
//Array of error descriptions
static char testing_errors[8][100]={
		"",//all OK
		"",//testing should report time
		_FATAL_ERROR_DURING_TEST_EXECUTION,
		_ERROR_BAD_POINTER_RETURNED,
		"",//if wrong values returned, testing function should write more specific message
		"",//if input data is wrong, testing function should write more specific message
		_ERROR_STUB_CALLED,
		""};//in case of wrong strcat/strcpy use secure function already printed specific message

////////////////////////////////////////////Internal function prototypes
//Table of test routines
void FillTestRoutines(void);
//Os-dependent: run thread for test function, arg is a pointer to function (__testroutine)
int __runTestThread(__testroutine arg);


//Table of test routines
void FillTestRoutines(void)
{
	//////var 1
	tstroutines[1][0][0]=_test_1_selectWords;
	tstroutines[1][0][1]=_test_1_findWord;
	//1mod6
	tstroutines[1][6][0]=_test_1_selectWords;
	tstroutines[1][6][1]=_test_1_findWord;
	tstroutines[1][6][2]=_test_530ec_textToStr;
	//1mod7
	tstroutines[1][7][0]=_test_1_findWord;
	tstroutines[1][7][1]=_test_59053_selectPhrases;
	tstroutines[1][7][2]=_test_530ec_textToStr;
	//1mod8
	tstroutines[1][8][0]=_test_1_findWord;
	tstroutines[1][8][1]=_test_454fb_cutString;

	//2
	tstroutines[2][0][0]=_test_2_textToWords;
	tstroutines[2][0][1]=_test_2_strToWords;
	//2mod6
	tstroutines[2][6][0]=_test_2_textToWords;
	tstroutines[2][6][1]=_test_2_strToWords;
	tstroutines[2][6][2]=_test_b4974_getWord;
	//2mod7
	tstroutines[2][7][0]=_test_2_textToWords;
	tstroutines[2][7][1]=_test_15_strToWords;
	//2mod8
	tstroutines[2][8][0]=_test_2_textToWords;
	tstroutines[2][8][1]=_test_16_strToWords;
	//2mod9
	tstroutines[2][9][0]=_test_2_textToWords;
	tstroutines[2][9][1]=_test_15_strToWords;
	tstroutines[2][9][2]=_test_4_cutString;

	//////var 3
	tstroutines[3][0][0]=_test_3_crossStrings;
	tstroutines[3][0][1]=_test_3_strToWords;
	//3mod6
	tstroutines[3][6][0]=_test_3_crossStrings;
	tstroutines[3][6][1]=_test_3_strToWords;
	tstroutines[3][6][2]=_test_93be5_countWords;
	//3mod7
	tstroutines[3][7][0]=_test_3_strToWords;
	tstroutines[3][7][1]=_test_c1d1b_uniteStrings;
	//3mod8
	tstroutines[3][8][0]=_test_3_crossStrings;
	tstroutines[3][8][1]=_test_3_strToWords;
	tstroutines[3][8][2]=_test_7e880_uniqueStrings;

	//////var 4
	tstroutines[4][0][0]=_test_4_delCharacters;
	tstroutines[4][0][1]=_test_4_cutString;
	//4mod6
	tstroutines[4][6][0]=_test_4_delCharacters;
	tstroutines[4][6][1]=_test_4_cutString;
	tstroutines[4][6][2]=_test_6ec83_delFromText;
	//4mod7
	tstroutines[4][7][0]=_test_4_cutString;
	tstroutines[4][7][1]=_test_1f2a9_delSubstring;
	//4mod8
	tstroutines[4][8][0]=_test_4_cutString;
	tstroutines[4][8][1]=_test_97af7_delWord;

	//////var 5
	tstroutines[5][0][0]=_test_5_textToWords;
	tstroutines[5][0][1]=_test_5_textLength;
	//5mod6
	tstroutines[5][6][0]=_test_5_textToWords;
	tstroutines[5][6][1]=_test_5_textLength;
	tstroutines[5][6][2]=_test_597e4_strToWords;
	//5mod7
	tstroutines[5][7][0]=_test_5_textToWords;
	tstroutines[5][7][1]=_test_a46a5_minimum;
	//5mod8
	tstroutines[5][8][0]=_test_5_textToWords;
	tstroutines[5][8][1]=_test_f579b_isEndOfSentence;

	//////var 6
	tstroutines[6][0][0]=_test_6_getNumbers;
	tstroutines[6][0][1]=_test_6_findInteger;
	//6mod6
	tstroutines[6][6][0]=_test_6_getNumbers;
	tstroutines[6][6][1]=_test_6_findInteger;
	tstroutines[6][6][2]=_test_beb12_getNumbersFromText;
	//6mod7
	tstroutines[6][7][0]=_test_8f7d2_getNumbers;
	tstroutines[6][7][1]=_test_8f7d2_findFloat;
	//6mod8
	tstroutines[6][8][0]=_test_8f7d2_getNumbers;
	tstroutines[6][8][1]=_test_8f7d2_findFloat;
	
	//////var 7
	tstroutines[7][0][0]=_test_3_strToWords;
	tstroutines[7][0][1]=_test_7_sortByStringLength;
	//7mod6
	tstroutines[7][6][0]=_test_2_strToWords;
	tstroutines[7][6][1]=_test_7_sortByStringLength;
	//7mod7
	tstroutines[7][7][0]=_test_3_strToWords;
	tstroutines[7][7][1]=_test_3643e_sortByStringLength;
	//7mod8
	tstroutines[7][8][0]=_test_3_strToWords;
	tstroutines[7][8][1]=_test_ae399_compareString;

	//////var 8
	tstroutines[8][0][0]=_test_8_insertString;
	tstroutines[8][0][1]=_test_8_findCharInText;
	//8mod6
	tstroutines[8][6][0]=_test_8_insertString;
	tstroutines[8][6][1]=_test_8_findCharInText;
	tstroutines[8][6][2]=_test_aaaa9_insertStringBefore;
	//8mod7
	tstroutines[8][7][0]=_test_8_insertString;
	tstroutines[8][7][1]=_test_622d9_findSubstrInText;
	//8mod8
	tstroutines[8][8][0]=_test_8_insertString;
	tstroutines[8][8][1]=_test_8_findCharInText;
	tstroutines[8][8][2]=_test_1191a_insertStrToText;

	//////var 9
	tstroutines[9][0][0]=_test_9_findPairBrackets;
	tstroutines[9][0][1]=_test_4_cutString;
	//9mod6
	tstroutines[9][6][0]=_test_9_findPairBrackets;
	tstroutines[9][6][1]=_test_4_cutString;
	tstroutines[9][6][2]=_test_1bec2_cutText;
	//9mod7
	tstroutines[9][7][0]=_test_9_findPairBrackets;
	tstroutines[9][7][1]=_test_4_cutString;
	tstroutines[9][7][2]=_test_7a70f_countInvalidBrackets;
	//9mod8
	tstroutines[9][8][0]=_test_9_findPairBrackets;
	tstroutines[9][8][1]=_test_4_cutString;
	tstroutines[9][8][2]=_test_c46f2_cutBracketsFromText;
	//9mod9
	tstroutines[9][9][0]=_test_9_findPairBrackets;
	tstroutines[9][9][1]=_test_4_cutString;
	tstroutines[9][9][2]=_test_c46f2_cutBracketsFromText;

	//////var 10
	tstroutines[10][0][0]=_test_10_markWords;
	tstroutines[10][0][1]=_test_10_searchWord;
	tstroutines[10][0][2]=_test_10_slideString;
	//10mod6
	tstroutines[10][6][0]=_test_10_markWords;
	tstroutines[10][6][1]=_test_10_searchWord;
	tstroutines[10][6][2]=_test_10_slideString;
	tstroutines[10][6][3]=_test_25b24_markWordsInText;
	//10mod7
	tstroutines[10][7][0]=_test_10_searchWord;
	tstroutines[10][7][1]=_test_10_slideString;
	tstroutines[10][7][2]=_test_efc2b_duplicateWords;
	//10mod8
	tstroutines[10][8][0]=_test_10_searchWord;
	tstroutines[10][8][1]=_test_10_slideString;
	tstroutines[10][8][2]=_test_e18c0_entryCount;

	//////var 11
	tstroutines[11][0][0]=_test_11_deleteBlanks;
	tstroutines[11][0][1]=_test_4_cutString;
	//11mod6
	tstroutines[11][6][0]=_test_11_deleteBlanks;
	tstroutines[11][6][1]=_test_4_cutString;
	tstroutines[11][6][2]=_test_eb290_deleteBlanksFromText;
	//11mod7
	tstroutines[11][7][0]=_test_11_deleteBlanks;
	tstroutines[11][7][1]=_test_4_cutString;
	tstroutines[11][7][2]=_test_3ec7d_deleteDelimiters;
	//11mod8
	tstroutines[11][8][0]=_test_eb290_deleteBlanksFromText;
	tstroutines[11][8][1]=_test_4_cutString;
	tstroutines[11][8][2]=_test_b37fd_findNextQuote;

	//////var 12
	tstroutines[12][0][0]=_test_3_strToWords;
	tstroutines[12][0][1]=_test_12_markWords;
	//12mod6
	tstroutines[12][6][0]=_test_3_strToWords;
	tstroutines[12][6][1]=_test_12_markWords;
	tstroutines[12][6][2]=_test_2ae70_compositionStrings;
	//12mod7
	tstroutines[12][7][0]=_test_3_strToWords;
	tstroutines[12][7][1]=_test_12_markWords;
	tstroutines[12][7][2]=_test_62a5d_compareStringList;
	//12mod8
	tstroutines[12][8][0]=_test_05967_strToWords;
	tstroutines[12][8][1]=_test_12_markWords;

	//////var 13
	tstroutines[13][0][0]=_test_13_searchString;
	tstroutines[13][0][1]=_test_13_slideStringList;
	//13mod6
	tstroutines[13][6][0]=_test_13_searchString;
	tstroutines[13][6][1]=_test_13_slideStringList;
	tstroutines[13][6][2]=_test_02b98_insertToStringList;
	//13mod7
	tstroutines[13][7][0]=_test_13_searchString;
	tstroutines[13][7][1]=_test_13_slideStringList;
	tstroutines[13][7][2]=_test_d5d5b_getRating;
	//13mod8
	tstroutines[13][8][0]=_test_13_searchString;
	tstroutines[13][8][1]=_test_13_slideStringList;
	tstroutines[13][8][2]=_test_69305_packStringList;

	//////var 14
	tstroutines[14][0][0]=_test_16_strToWords;
	tstroutines[14][0][1]=_test_14_countWordsByLetter;
	//14mod6
	tstroutines[14][6][0]=_test_16_strToWords;
	tstroutines[14][6][1]=_test_14_countWordsByLetter;
	tstroutines[14][6][2]=_test_a120f_startWords;
	//14mod7
	tstroutines[14][7][0]=_test_16_strToWords;
	tstroutines[14][7][1]=_test_2ffe4_startWords;
	//14mod8
	tstroutines[14][8][0]=_test_16_strToWords;
	tstroutines[14][8][1]=_test_0523c_lettersString;

	//////var 15
	tstroutines[15][0][0]=_test_15_strToWords;
	tstroutines[15][0][1]=_test_15_compareByContents;
	//15mod6
	tstroutines[15][6][0]=_test_15_strToWords;
	tstroutines[15][6][1]=_test_15_compareByContents;
	tstroutines[15][6][2]=_test_f8595_equalWords;
	//15mod7
	tstroutines[15][7][0]=_test_15_strToWords;
	tstroutines[15][7][1]=_test_a77a5_differenceByContents;
	//15mod8
	tstroutines[15][8][0]=_test_15_strToWords;
	tstroutines[15][8][1]=_test_a77a5_differenceByContents;

	//////var 16
	tstroutines[16][0][0]=_test_16_strToWords;
	tstroutines[16][0][1]=_test_16_selectWords;
	//16mod6
	tstroutines[16][6][0]=_test_16_strToWords;
	tstroutines[16][6][1]=_test_16_selectWords;
	tstroutines[16][6][2]=_test_16mods67_findWordFromText;
	//16mod7
	tstroutines[16][7][0]=_test_16_strToWords;
	tstroutines[16][7][1]=_test_16_selectWords;
	tstroutines[16][7][2]=_test_16mods67_findWordFromText;
	//16mod8
	tstroutines[16][8][0]=_test_16_strToWords;
	tstroutines[16][8][1]=_test_142d2_findFIO;

	//////var 17
	tstroutines[17][0][0]=_test_17_reverseWords;
	tstroutines[17][0][1]=_test_10_searchWord;
	//17mod6
	tstroutines[17][6][0]=_test_17_reverseWords;
	tstroutines[17][6][1]=_test_10_searchWord;
	tstroutines[17][6][2]=_test_a7490_reverseWordsInText;
	//17mod7
	tstroutines[17][7][0]=_test_10_searchWord;
	tstroutines[17][7][1]=_test_f3c74_reversePhrase;
	//17mod8
	tstroutines[17][8][0]=_test_10_searchWord;
	tstroutines[17][8][1]=_test_05789_reversePhraseInText;
	
	//////var 18
	tstroutines[18][0][0]=_test_18_deleteWords;
	tstroutines[18][0][1]=_test_10_searchWord;
	tstroutines[18][0][2]=_test_4_cutString;
	//18mod6
	tstroutines[18][6][0]=_test_18_deleteWords;
	tstroutines[18][6][1]=_test_10_searchWord;
	tstroutines[18][6][2]=_test_4_cutString;
	tstroutines[18][6][3]=_test_3eac1_deleteWordsFromText;
	//18mod7
	tstroutines[18][7][0]=_test_18_deleteWords;
	tstroutines[18][7][1]=_test_10_searchWord;
	tstroutines[18][7][2]=_test_4_cutString;
	tstroutines[18][7][3]=_test_1af88_deleteString;
	//18mod8
	tstroutines[18][8][0]=_test_10_searchWord;
	tstroutines[18][8][1]=_test_4_cutString;
	tstroutines[18][8][2]=_test_50b16_deleteDuplicateWordsFromText;

	//////var 19
	tstroutines[19][0][0]=_test_19_toMorseCode;
	tstroutines[19][0][1]=_test_19_strToMorse;
	//19mod6
	tstroutines[19][6][0]=_test_19_toMorseCode;
	tstroutines[19][6][1]=_test_19_strToMorse;
	tstroutines[19][6][2]=_test_f3342_translateText;
	//19mod7
	tstroutines[19][7][0]=_test_19_toMorseCode;
	tstroutines[19][7][1]=_test_fc6a9_translateSubstrings;
	//19mod8
	tstroutines[19][8][0]=_test_fa4a6_translateFromMorseCode;

	//////var 20
	tstroutines[20][0][0]=_test_20_searchPhrase;
	tstroutines[20][0][1]=_test_15_strToWords;
	//20mod6
	tstroutines[20][6][0]=_test_20_searchPhrase;
	tstroutines[20][6][1]=_test_15_strToWords;
	tstroutines[20][6][2]=_test_6a4eb_searchWordInText;
	//20mod7
	tstroutines[20][7][0]=_test_20_searchPhrase;
	tstroutines[20][7][1]=_test_15_strToWords;
	tstroutines[20][7][2]=_test_024d7_searchWordInText;
	//20mod8
	tstroutines[20][8][0]=_test_15_strToWords;
	tstroutines[20][8][1]=_test_04ca43_searchPhrase;

	//////var 21
	tstroutines[21][0][0]=_test_21_replaceWords;
	tstroutines[21][0][1]=_test_10_searchWord;
	//21mod6
	tstroutines[21][6][0]=_test_21_replaceWords;
	tstroutines[21][6][1]=_test_10_searchWord;
	tstroutines[21][6][2]=_test_d2e14_replaceWordsInText;
	//21mod7
	tstroutines[21][7][0]=_test_21_replaceWords;
	tstroutines[21][7][1]=_test_10_searchWord;
	tstroutines[21][7][2]=_test_4_cutString;
	//21mod8
	tstroutines[21][8][0]=_test_10_searchWord;
	tstroutines[21][8][1]=_test_e3a83_insertStringToText;

	//////var 22
	tstroutines[22][0][0]=_test_22_stringToSubstrings;
	tstroutines[22][0][1]=_test_22_countRepeats;
	//22mod6
	tstroutines[22][6][0]=_test_22_stringToSubstrings;
	tstroutines[22][6][1]=_test_22_countRepeats;
	tstroutines[22][6][2]=_test_235bc_iterativeWordCount;
	//22mod7
	tstroutines[22][7][0]=_test_22_stringToSubstrings;
	tstroutines[22][7][1]=_test_a4eb3_iterativeWordLocation;
	//22mod8
	tstroutines[22][8][0]=_test_22_stringToSubstrings;
	tstroutines[22][8][1]=_test_fcb68_sentenceLocation;

	//////var 23
	tstroutines[23][0][0]=_test_23_wordMeaning;
	tstroutines[23][0][1]=_test_23_strToWords;
	//23mod6
	tstroutines[23][6][0]=_test_23_wordMeaning;
	tstroutines[23][6][1]=_test_23_strToWords;
	tstroutines[23][6][2]=_test_b40a3_distanceBetweenWords;
	//23mod7
	tstroutines[23][7][0]=_test_23_wordMeaning;
	tstroutines[23][7][1]=_test_23_strToWords;
	tstroutines[23][7][2]=_test_24cb3_getWords;
	//23mod6
	tstroutines[23][8][0]=_test_23_strToWords;
	tstroutines[23][8][1]=_test_63e44_separateToSentences;

	//////var 24
	tstroutines[24][0][0]=_test_24_stringInText;
	tstroutines[24][0][1]=_test_15_strToWords;
	//24mod6
	tstroutines[24][6][0]=_test_24_stringInText;
	tstroutines[24][6][1]=_test_15_strToWords;
	tstroutines[24][6][2]=_test_65b6e_stringInTextAll;
	//24mod7
	tstroutines[24][7][0]=_test_24_stringInText;
	tstroutines[24][7][1]=_test_15_strToWords;
	tstroutines[24][7][2]=_test_84c95_delRegionOfText;
	//24mod8
	tstroutines[24][8][0]=_test_24_stringInText;
	tstroutines[24][8][1]=_test_15_strToWords;
	tstroutines[24][8][2]=_test_8eb83_appendString;
	//24mod9
	tstroutines[24][9][0]=_test_24_stringInText;
	tstroutines[24][9][1]=_test_15_strToWords;
	tstroutines[24][9][2]=_test_8eb83_appendString;

	//////var 25
	tstroutines[25][0][0]=_test_25_parseSynonym;
	tstroutines[25][0][1]=_test_25_findSynonym;
	//25mod6
	tstroutines[25][6][0]=_test_25_parseSynonym;
	tstroutines[25][6][1]=_test_25_findSynonym;
	tstroutines[25][6][2]=_test_20579_findSynonymAll;
	//25mod7
	tstroutines[25][7][0]=_test_25_parseSynonym;
	tstroutines[25][7][1]=_test_25_findSynonym;
	tstroutines[25][7][2]=_test_d9542_synonymString;
	//25mod8
	tstroutines[25][8][0]=_test_25_parseSynonym;
	tstroutines[25][8][1]=_test_25_findSynonym;
	tstroutines[25][8][2]=_test_2ae89_addSynonyms;

	//////var 26
	tstroutines[26][0][0]=_test_3_strToWords;
	tstroutines[26][0][1]=_test_26_findString;
	//26mod6
	tstroutines[26][6][0]=_test_3_strToWords;
	tstroutines[26][6][1]=_test_26_findString;
	tstroutines[26][6][2]=_test_54ded_spellString;
	//26mod7
	tstroutines[26][7][0]=_test_3_strToWords;
	tstroutines[26][7][1]=_test_26_findString;
	tstroutines[26][7][2]=_test_e82bb_checkSpelling;
	//26mod8
	tstroutines[26][8][0]=_test_3_strToWords;
	tstroutines[26][8][1]=_test_26_findString;
	tstroutines[26][8][2]=_test_0a49d_fixSpelling;

	//////var 27
	tstroutines[27][0][0]=_test_27_findWord;
	tstroutines[27][0][1]=_test_27_divideWord;
	//27mod6
	tstroutines[27][6][0]=_test_27_findWord;
	tstroutines[27][6][1]=_test_27_divideWord;
	tstroutines[27][6][2]=_test_27cd9_divisionOfWordInDictionary;
	//27mod7
	tstroutines[27][7][0]=_test_27_findWord;
	tstroutines[27][7][1]=_test_27_divideWord;
	tstroutines[27][7][2]=_test_bb159_divideString;
	//27mod8
	tstroutines[27][8][0]=_test_27_findWord;
	tstroutines[27][8][1]=_test_27_divideWord;
	tstroutines[27][8][2]=_test_bb159_divideString;

	//////var 28
	tstroutines[28][0][0]=_test_10_slideString;
	tstroutines[28][0][1]=_test_4_cutString;
	//28mod6
	tstroutines[28][6][0]=_test_10_slideString;
	tstroutines[28][6][1]=_test_4_cutString;
	tstroutines[28][6][2]=_test_ce079_insertFirstLineIndent;
	//28mod7
	tstroutines[28][7][0]=_test_10_slideString;
	tstroutines[28][7][1]=_test_4_cutString;
	tstroutines[28][7][2]=_test_d26a2_insertEmptyString;
	//28mod8
	tstroutines[28][8][0]=_test_10_slideString;
	tstroutines[28][8][1]=_test_4_cutString;
	tstroutines[28][8][2]=_test_df735_insertString;

	//////var 29
	tstroutines[29][0][0]=_test_29_distanceBetweenWords;
	tstroutines[29][0][1]=_test_10_searchWord;
	//29mod6
	tstroutines[29][6][0]=_test_29_distanceBetweenWords;
	tstroutines[29][6][1]=_test_10_searchWord;
	tstroutines[29][6][2]=_test_10c6c_distanceBetweenWordsValue;
	//29mod7
	tstroutines[29][7][0]=_test_10_searchWord;
	tstroutines[29][7][1]=_test_5ebf2_fillLettersAndNumbers;
	//29mod8
	tstroutines[29][8][0]=_test_10_searchWord;
	tstroutines[29][8][1]=_test_64dd0_distanceBeetwenPhrases;

	//////var 30
	tstroutines[30][0][0]=_test_30_censorWords;
	tstroutines[30][0][1]=_test_10_searchWord;
	//30mod6
	tstroutines[30][6][0]=_test_30_censorWords;
	tstroutines[30][6][1]=_test_10_searchWord;
	tstroutines[30][6][2]=_test_5d510_censorText;
	//30mod7
	tstroutines[30][7][0]=_test_10_searchWord;
	tstroutines[30][7][1]=_test_5d510_censorText;
	//30mod8
	tstroutines[30][8][0]=_test_10_searchWord;
	tstroutines[30][8][1]=_test_5d510_censorText;

}

// #1
int (*_1_selectWords)(const char *str, int min, int max, char words[30][21]);
void (*_1_findWord)(const char *str, int start, int *begin, int *end);
//1mod6
void (*_530ec_textToStr)(const char text[20][81], int strCount, char str[1621]);
//1mod7
int (*_59053_selectPhrases)(const char str[1621],int min, int max, char phrases[30][41]);
//1mod8
void (*_454fb_cutString) (char str[21], int max);

// #2
int (*_2_textToWords)(const char text[20][81], int strCount, char words[40][21]);
int (*_2_strToWords)(const char *str, int start, char words[40][21]);
//2mod6
void (*_b4974_getWord)(const char text[20][81], int strCount, int index, char word[21]);
//use _test_16_strToWords and _test_15_strToWords to test other mods

// #3
int (*_3_crossStrings) (const char str1[81], const char str2[81], char words[40][21]);
int (*_3_strToWords)(const char str[81], char words[40][21]);
//3mod6
int (*_93be5_countWords)(const char words[40][21],int count,const char word[21]);
//3mod7
int (*_c1d1b_uniteStrings) (const char str1[81], const char str2[81], char words[40][21]);
//3mod8
int (*_7e880_uniqueStrings)(char stringList[40][21], int strCount);


// #4
void (*_4_delCharacters) (char str[81], const char characters[256]);
void (*_4_cutString) (char str[81], int beginPos, int endPos);
//4mod6
void (*_6ec83_delFromText)(char text[20][81], int strCount, const char characters[256]);
//4mod7
void (*_1f2a9_delSubstring) (char str[81], const char substring[81]);
//4mod8
void (*_97af7_delWord) (char str[81], const char word[21]);

// #5
int (*_5_textToWords) (const char text[20][81], int strCount, char *words[800], char wordLength[800]);
int (*_5_textLength)(const char text[20][81], int strCount);
//5mod6
int (*_597e4_strToWords) (const char str[81], int start, char *words[800], char wordLength[800]);
//5mod7
int (*_a46a5_minimum) (const char arr[800], int count, int mins[800]);
//5mod8
int (*_f579b_isEndOfSentence) (const char text[20][81], int N, char * const word);

// #6
int (*_6_getNumbers) (const char str[81], int numbers[40]);
int (*_6_findInteger)(const char str[81], char **end);
//6mod6
int (*_beb12_getNumbersFromText)(const char text[20][81], int strCount, int numbers[40]);
//6mod78
int (*_8f7d2_getNumbers) (const char str[81], float numbers[40]);
float (*_8f7d2_findFloat)(const char * str, char **end);

// #7
void (*_7_sortByStringLength)(char stringList[30][21], int count);
//using _3_strToWords
//using _2_strToWords
//7mod7
void (*_3643e_sortByStringLength)(char stringList[30][21], int count, int direction);
//7mod8
int (*_ae399_compareString)(const char str1[21], const char str2[21], const char alphabet[256]);

// #8
int (*_8_insertString) (char destinString[81], const char sourceString[81],  int characterIndex);
int (*_8_findCharInText)(const char text[20][81], int N, char character, int *line, int *column);
//8mod6
void (*_aaaa9_insertStringBefore)(char text[20][81],int N, const char str[81], char character);
//8mod7
int (*_622d9_findSubstrInText) (const char text[20][81], int strCount, char substring[81], int * line, int * column);
//8mod8
int (*_1191a_insertStrToText) (char text[20][81], int strCount, const char str[81], int strIndex);

// #9
void (*_9_findPairBrackets) (const char text[20][81], int strCount, int lineIndex, int characterIndex, int brackets[4]);
//using _4_cutString
//9mod6
int (*_1bec2_cutText)(char text[20][81],int strCount,int startStrIndex, int startCharIndex, int endStrIndex, int endCharIndex);
//9mod7
int (*_7a70f_countInvalidBrackets) (char text[20][81], int strCount, int errors[60][2]);
//9mod 8 & 9
int (*_c46f2_cutBracketsFromText) (char text[20][81], int strCount);

// #10
void (*_10_markWords)(char str[81], const char word[21]);
int (*_10_searchWord)(const char str[81], const char word[21]);
void (*_10_slideString)(char str[81], int pos, int growth, char spacer);
//10mod6
void (*_25b24_markWordsInText)(char text[20][81],int strCount, const char word[21]);
//10mod7
void (*_efc2b_duplicateWords)(char text[20][81], int strCount, const char word[21]);
//10mod8
int (*_e18c0_entryCount)(const char text[20][81], int strCount, const char word[21]);

// #11
void (*_11_deleteBlanks)(char str[81]);
//using _4_cutString
//11mod6 & 8
void (*_eb290_deleteBlanksFromText)(char text[20][81], int strCount);
//11mod7
void (*_3ec7d_deleteDelimiters)(char str[81]);
//11mod8
int (*_b37fd_findNextQuote)(char text[20][81], int strCount, int *line,int *column);

// #12
//using _3_strToWords
int (*_12_markWords)(const char word[21], const char words[40][21], int nWords,int isEqual[40]);
//12mod6
int (*_2ae70_compositionStrings)(const char str1[81], const char str2[81]);
//12mod7
int (*_62a5d_compareStringList) (const char stringList1[40][21], int count1, const char stringList2[40][21], int count2);
//12mod8
int (*_05967_strToWords) (const char str[81], char words[40][21], char delimeters[81]);

// #13
int (*_13_searchString) (const char stringList[30][41], int count, const char str[41]);
int (*_13_slideStringList) (char stringList[30][41], int count, int strIndex);
//13mod6
void (*_02b98_insertToStringList)(char stringList[30][41], int count, const char str[41]);
//13mod7
float (*_d5d5b_getRating)(char str[41]);
//13mod8
int (*_69305_packStringList) (char stringList[30][41], int count, int strIndex);

// #14
//using _16_strToWords
void (*_14_countWordsByLetter) (char * const words[40], const int wordLength[40], int wordCount, int letters[32]);
//14mod6
int (*_a120f_startWords) (const char text[20][81], char letters[33]);
//14mod7
int (*_2ffe4_startWords) (char * const words[40], int count, const char character);
//14mod8
int (*_0523c_lettersString) (const char str[21]);

// #15
int (*_15_strToWords) (const char str[81], int words[40][2]);
int (*_15_compareByContents)(const char str1[21], const char str2[21]);
//15mod6
int (*_f8595_equalWords)(const char str[81], char word_groups[10][10][21]);
//15mod78
int (*_a77a5_differenceByContents)(const char str1[21], const char str2[21]);

// #16
int (*_16_strToWords)(const char str[81], char *words[40], int wordLength[40]);
int (*_16_selectWords)(char * const words[40],const int wordLength[40], int wordCount, const char prefix[40],int wordIndexes[40]);
//16mod67
int (*_58b3b_findWordFromText)(const char text[20][81], int count, const char prefix[21], char words[30][21]);
//16mod8
int (*_142d2_findFIO) (const char str[81], const char surname[21], int location[30]);

// #17
void (*_17_reverseWords)(char str[81], const char word[21]);
//using _10_searchWord
//17mod6
void (*_a7490_reverseWordsInText)(char text[20][81], int strCount,const char word[21]);
//17mod7
void (*_f3c74_reversePhrase)(char str[81], const char word1[21], const char word2[21]);
//17mod8
void (*_05789_reversePhraseInText)(char text[20][81], int strCount, const char word1[21], const char word2[21]);

// #18
void (*_18_deleteWords)(char str[81], const char word[21]);
//using _10_searchWord
//using _4_cutString
//18mod6
void(*_3eac1_deleteWordsFromText)(char text[20][81],int strCount, const char word[21]);
//18mod7
int (*_1af88_deleteString)(char text[20][81], int strCount, int index);
//18mod8
void (*_50b16_deleteDuplicateWordsFromText)(char text[20][81], int strCount);

// #19
void (*_19_toMorseCode)(char symbol, char MorseCode[7]);
void (*_19_strToMorse)(const char str[81],char MorseCode[324]);
//19mod6
void (*_f3342_translateText)(char text[20][324],char strCount);
//19mod7
void (*_fc6a9_translateSubstrings)(char str[81], const char substrings[20][31], int substrCount);
//19mod8
void (*_fa4a6_translateFromMorseCode)(const char strMorseCode[324], char str[81]);

// #20
int (*_20_searchPhrase)(const char text[20][81], int strCount, const char phrase[41], int location[40][2]);
//using _15_strToWords
//20mod6
int (*_6a4eb_searchWordInText)(const char text[20][81], int strCount, const char word[21], int location[40][2]);
//20mod7
void (*_024d7_searchWordInText)(const char text[20][81], int strCount, const char word[21], int direction, int location[2]);
//20mod8
int (*_04ca43_searchPhrase)(const char text[20][81], int strCount, const char phrase[20][41], int wordCount, int location[40][2]);

// #21
void (*_21_replaceWords )(char str[81], const char originalWord[21], const char targetWord[21]);
//using _10_searchWord
//21mod6
void (*_d2e14_replaceWordsInText)(char text[20][81], int strCount, const char originalWord[21], const char targetWord[21]);
//21mod7
//using _4_cutString
//21mod8
int (*_e3a83_insertStringToText)(char text[20][81], int strCount, const int location[2],const char substr[21]);

// #22
int (*_22_stringToSubstrings)(const char str[81], const char separators[31], char *substrings[30][2]);
int (*_22_countRepeats)(const char str[81], char * const substrings[30][2], int countSubstrings, char *startpos);
//22mod6
int (*_235bc_iterativeWordCount) (const char str[81], const char separators[31], int separator);
//22mod7
int (*_a4eb3_iterativeWordLocation)(const char text[20][81], int strCount, int location[40][2]);
//22mod8
int (*_fcb68_sentenceLocation) (const char text[20][81], int strCount, int location[40][2]);

// #23
int (*_23_wordMeaning)(const char str[81],const char word[21],const char satellites[5][21], int range);
int (*_23_strToWords)(const char str[81], char *words[40][2]);
//23mod6
int (*_b40a3_distanceBetweenWords) (const char str[81], const char word1[21], const char word2[21]);
//23mod7
int (*_24cb3_getWords)(const char str[81],int startIndex, int endIndex, char selectWords[20][21]);
//23mod8
int (*_63e44_separateToSentences) (const char str[81], char sentences [20][81]);

// #24
void (*_24_stringInText)(const char text[20][81], int strCount, const char str[81], int *lineIndex, int *colIndex);
//using _15_strToWords
//24mod6
int (*_65b6e_stringInTextAll)(const char text[20][81], int strCount, const char str[81], int location[20][2]);
//24mod7
void (*_84c95_delRegionOfText) (char text[20][81], int count, const int region[4]);
//24mod8&9
void (*_8eb83_appendString) (char destinationStr[81],const char sourceStr[81], int place, char excessive[81]);

// #25
int (*_25_parseSynonym)(const char synonym[61],char synonymDictionary[2][31]);
void (*_25_findSynonym)(const char synonymDictionary[20][2][31],int count, const char word[31], char synonym[31]);
//25mod6
int (*_20579_findSynonymAll)(const char synonymDictionary[20][2][31],int count, const char word[31], char synonyms[20][31]);
//25mod7
void (*_d9542_synonymString) (const char synonymDictionary[20][2][31], int count, const char sourceStr[81], char resultStr[81]);
//25mod8
void (*_2ae89_addSynonyms) (const char synonymDictionary[20][2][31], int count, char str[81]);

// #26
//using _3_strToWords
int (*_26_findString) (const char stringList[20][21], int count, const char str[21]);
//26mod6
int (*_54ded_spellString)(const char str[81], const char dictionary[20][21], int count);
//26mod7
void (*_e82bb_checkSpelling)(const char dictionary[20][21], int count, const char str[81], char checkedString[81]);
//26mod8
int (*_0a49d_fixSpelling)(const char dictionary[20][21], int count, char str[81]);

// #27
int (*_27_findWord)(const char divisionOfWords[20][2][31], int count, const char word[21]);
int (*_27_divideWord)(const char divisionOfWord[31], int n);
//27mod6
int (*_27cd9_divisionOfWordInDictionary)(const char divisionOfWords[20][2][31], int count, const char word[21], int n, int *hyphenIndex);
//27mod7&8
void (*_bb159_divideString) (const char divisionOfWords [20][2][31], int count, char str[81], int maxLength);

// #28
//using _10_slideString
//using _4_cutString
//28mod6
void (*_ce079_insertFirstLineIndent)(char text[20][81], int count);
//28mod7
int (*_d26a2_insertEmptyString) (char text[20][81], int count, int index);
//28mod8
int (*_df735_insertString) (char text[20][81], int count, int index, const char str[81]);

// #29
int (*_29_distanceBetweenWords)(const char text[20][81], int count,const int locationWord1[2],const int locationWord2[2]);
//using _10_searchWord
//29mod6
int (*_10c6c_distanceBetweenWordsValue)(const char text[20][81], int count,const char word1[21], const char word2[21]);
//29mod7
int (*_5ebf2_fillLettersAndNumbers)(char text[20][81], int count, int locationWord1[2], int locationWord2[2]);
//29mod8
int (*_64dd0_distanceBeetwenPhrases)(const char text[20][81], int count, const char phrase1[41], const char phrase2[41]);

// #30
void (*_30_censorWords) (char str[81], const char word[21]);
//using _10_searchWord
//30mod6, 7 & 8
void (*_5d510_censorText)(char text[20][81], int count,const char * word);

#ifdef _WIN32
////Start of Microsoft Visual Studio  section
//Please move all Windows/Microsoft Visual Studio - specific code there once it will be discovered
//Look for examples below
#include <windows.h> //Sorry, there is no CRTL equivalent of Sleep function, and _beginthread isn't platform independent too

//test thread function, arg is a pointer to actual function to execute
DWORD WINAPI __UnitTestThread(LPVOID arg)
{
	__testroutine tstrout=(__testroutine)arg;
	int res=tstrout(funcstream, ostream);
	fflush(ostream);
	return res;
}
//Running test thread and kill it after execution
//arg is a pointer to the testing routine
//return value - cf. macro in internal.h
int __runTestThread(__testroutine arg)
{
	DWORD returnCode;
	HANDLE hThread=CreateThread(NULL,0,__UnitTestThread,(LPVOID)arg,0,0);
	DWORD waitres=WaitForSingleObject(hThread,(DWORD)(1000*testingtime));
	if(waitres==WAIT_TIMEOUT)
	{
		TerminateThread(hThread,TESTRES_TIMEOUT);
		fprintf(ostream,_ERROR_TEST_TIMEOUT,testingtime);
		return TESTRES_TIMEOUT;
	}
	GetExitCodeThread(hThread,&returnCode);
	return returnCode;
	
}
#endif


void UnitTesting(void)
{
	char buffer[300];
	//Tested function number (for classwork first numbers given to homework functions, then added classwork functions)
	int funcnumber=-1;
	//Variant
	int variant=-1;
	//0 for homework, 1 etc for classwork
	int report=-1;
	//Input (global) file stream
	FILE *istream;
	//Result of test execution
	int testres;

	/////////////////Init testing data
	ostream=NULL;
	char * tmpstr=getenv("variantnumber");
	variant=atoi(tmpstr);
	tmpstr=getenv("reportnumber");
	report=atoi(tmpstr);
	//By default, testing time is 1 second per test (including reading and writing test data)
	//You could override it using environment variable "testingtime", specifying time in seconds
	testingtime=1;
	tmpstr = getenv("testingtime");
	if(tmpstr != NULL)
	{
		float usertime=(float)atof(tmpstr);
		if(usertime>0)
			testingtime=usertime;
	}
	//Get path to input files from environment variable set by autotester
	char *pathstr=getenv("pathtofiles");
	strcpy(buffer,pathstr);
	//Global input file is "str_unit.txt"
	strcat(buffer,"str_unit.txt");
	istream=fopen(buffer, "rt");
	if(istream==NULL)
		printf(_ERROR_CANT_OPEN_INPUT_FILE,tmpstr);
	//Get output file name from environment variable set by autotester
	tmpstr=getenv("outputfile");
	ostream=fopen(tmpstr,"wt");
	if(ostream==NULL)
		printf(_ERROR_CANT_OPEN_OUTPUT_FILE,tmpstr);

	FillTestRoutines();

	////////////////Perform testing
	while(!feof(istream))
	{
		if(read_string_raw(buffer,300,istream)!=NULL)
		{
			//printing tested function prototype
			fprintf(ostream,"%s\n",buffer);
			funcnumber++;
			//open file with input data to the function
			strcpy(buffer,pathstr);
			read_string_raw(buffer+strlen(buffer),300,istream);
			funcstream=fopen(buffer,"rt");
			if(funcstream==NULL)
			{
				fprintf(ostream,_ERROR_NO_INPUT_DATA,buffer);
			}
			else
			{
				int numoftests;
				//read number of tests
				fgets(buffer,300,funcstream);
				numoftests=atoi(buffer);
				__stub_called = 0;
				for(int i=0;i<numoftests && !__stub_called;i++)//if stub is called there is no point in test execution
				{
					//Read and print test name
					read_string_raw(buffer,300,funcstream);
					fprintf(ostream,"%s\n",buffer);
					//perform testing
					if(tstroutines[variant][report][funcnumber]!=NULL)
						testres=__runTestThread(tstroutines[variant][report][funcnumber]);
					if(testres)
						fprintf(ostream,"%s",testing_errors[testres]);
					fprintf(ostream,"\n");
				}

				fclose(funcstream);
				fprintf(ostream,"\n");
			}
		}//if(fgets(buffer,300,istream)!=NULL)
	}//while(!feof(istream))

	fclose(istream);
	fclose(ostream);
}

char * secure_strcat(char * dest, const char * src)
{
	if(abs(dest+strlen(dest)-src)<strlen(src))
	{
		fprintf(ostream,_ERROR_BAD_STRCAT_CALL,src,dest);
		_wrong_strcat_strcpy=1;
		return dest;
	}
	else
		return strcat(dest,src);
}
char * secure_strcpy(char * dest, const char * src)
{
	if(abs(dest-src)<strlen(src))
	{
		fprintf(ostream,_ERROR_BAD_STRCPY_CALL,src);
		_wrong_strcat_strcpy=1;
		return dest;
	}
	else
		return strcpy(dest,src);
}